package com.multimedia.room.view;

import android.content.Context;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ImageView;


/**
 * Base imageview with animation drawable support for music
 *
 * @author brlygolo
 */
public abstract class MusicAnimationDrawableView extends ImageView {

    public static final String TAG = "MusicAnimation";
    public static final boolean DEBUG = false;

    private static final int MSG_LOOP_ANIMATION_START = 1;
    private static final int MSG_END_ANIMATION_START = 2;
    private static final int MSG_HIDE = 3;
    private static final int MSG_PAUSE = 4;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            stopAnimation(false);

            if (DEBUG) Log.d(TAG, "handleMessage: " + msg.what + ", " + MusicAnimationDrawableView.this);

            int res = 0;
            switch (msg.what) {
                case MSG_LOOP_ANIMATION_START:
                    res = getLoopAnimationResource();
                    break;
                case MSG_END_ANIMATION_START:
                    res = getEndAnimationResource();
                    break;
                case MSG_HIDE:
                    setImageDrawable(null);
                    return;
                case MSG_PAUSE:
                    stopped();
                    return;
                default:
                    super.handleMessage(msg);
                    break;
            }

            AnimationDrawable animationDrawable = (AnimationDrawable) getContext().getResources().getDrawable(res);
            setImageDrawable(animationDrawable);
            animationDrawable.start();
        }
    };

    public MusicAnimationDrawableView(Context context) {
        super(context);
    }

    public MusicAnimationDrawableView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MusicAnimationDrawableView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    /**
     * Replacing current drawable with playing animation
     */
    public void start() {
        mHandler.removeMessages(MSG_LOOP_ANIMATION_START);
        mHandler.removeMessages(MSG_END_ANIMATION_START);
        mHandler.sendEmptyMessage(MSG_LOOP_ANIMATION_START);
    }

    /**
     * Replacing current drawable with stop oneshot animation
     */
    public void stop() {
        mHandler.removeMessages(MSG_LOOP_ANIMATION_START);
        mHandler.removeMessages(MSG_END_ANIMATION_START);
        mHandler.sendEmptyMessage(MSG_END_ANIMATION_START);
    }

    public void pause() {
        mHandler.removeMessages(MSG_PAUSE);
        mHandler.sendEmptyMessage(MSG_PAUSE);
    }

    /**
     * indicate paused/stopped player
     */
    public void stopped() {
        if (DEBUG) Log.d(TAG, "stopped, " + this);
        stopAnimation();
        setImageResource(getStoppedResource());
    }

    /**
     * Make icon fully hidden
     */
    public void hide() {
        mHandler.sendEmptyMessage(MSG_HIDE);
    }

    protected void stopAnimation() {
        stopAnimation(true);
    }

    /**
     * Stops current animation if it is active
     */
    protected void stopAnimation(boolean cancelPending) {
        if (cancelPending) {
            mHandler.removeCallbacksAndMessages(null);
        }
        Drawable drawable = getDrawable();
        AnimationDrawable animationDrawable;
        if (drawable instanceof AnimationDrawable) {
            animationDrawable = (AnimationDrawable) drawable;
            if (animationDrawable != null && animationDrawable.isRunning()) {
                animationDrawable.stop();
            }
        }
    }

    /**
     * loop animation drawable
     * @return resource id
     */
    protected abstract int getLoopAnimationResource();

    /**
     * end animation drawable
     * @return resource id
     */
    protected abstract int getEndAnimationResource();

    /**
     * stopped/paused drawable
     * @return resource id
     */
    protected abstract int getStoppedResource();
}
